package com.aibaixun.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.aibaixun.common.constant.ApiConstants;
import com.aibaixun.common.constant.Constants;
import com.aibaixun.common.core.domain.R;
import com.aibaixun.common.utils.HttpUtils;
import com.aibaixun.common.utils.StringUtils;
import com.aibaixun.system.domain.*;
import com.aibaixun.system.domain.dto.DicmAddressData;
import com.aibaixun.system.domain.dto.DicmNvrRegisterDto;
import com.aibaixun.system.domain.dto.DicmPostureDeviceDto;
import com.aibaixun.system.domain.dto.QueryPostureDeviceDto;
import com.aibaixun.system.domain.vo.AssetsMessageVo;
import com.aibaixun.system.domain.vo.SeatMessageVo;
import com.aibaixun.system.domain.vo.SeatVo;
import com.aibaixun.system.service.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.squareup.okhttp.*;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * EVS API调用 服务层实现
 *
 * @author zhangyh
 */
@RequiredArgsConstructor
@Service
public class EvsApiServiceImpl implements EvsApiService {

    @Autowired
    private DicmNvrService dicmNvrService;

    @Autowired
    private DicmAddressService dicmAddressService;

    @Autowired
    @Lazy
    private DicmWorkOrderService dicmWorkOrderService;

    @Autowired
    private WorkOrderUserService workOrderUserService;

    @Autowired
    private WorkOrderAlarmService workOrderAlarmService;

    @Autowired
    private EvsHumanEventService evsHumanEventService;

    @Autowired
    private EvsDoorEventService evsDoorEventService;

    @Autowired
    private PostureDeviceService postureDeviceService;

    @Autowired
    private DicmDeviceService dicmDeviceService;

    @Autowired
    private DicmCabinetService dicmCabinetService;

    @Autowired
    private DicmAddressDataService dicmAddressDataService;

    @Autowired
    private PostureDeviceNewService postureDeviceNewService;


    private static final Logger logger = LoggerFactory.getLogger(EvsApiServiceImpl.class);

    //公有云环境
//    private final static String AK = "ALTAKn9KUT2rqPu6ycC7DP0Gn8";
//    private final static String SK = "3e0c6c3355b846378dc4d254c282c8b4";
//    private final static String endpoint_cloud = "https://evs.bj.baidubce.com/";

    //贵安私有云环境
    private final static String AK = "guianadmin";
    private final static String SK = "guian@123";
    private final static String endpoint = "http://10.195.216.20:8765/";
    private final static String endpoint_ai = "http://10.195.216.20:8760/";
    private final static String space_id = "1000002";
    private final static String project_id = "3";
    private final static String database_id = "dbf-djrs96gxid1dseqg";
    private final static String human_app_id = "app-djrst5cnssbzgyhw";
    private final static String door_app_id = "app-djtsh8eugshr6wxd";

    @Override
    public String addEvsMember(WorkOrderUser user) {
        //上传人脸照片
        Object uploadFileData = sendOkHttpClientFile(endpoint_ai+"v1/ai/databases/"+database_id+"/pic?uploadAuth"
            , "GET", user.getPersonPhoto());
        if(uploadFileData == null){
            return null;
        }
        JSONObject paramData = new JSONObject();
        paramData.put("picKey",uploadFileData.toString());
        JSONObject userData = new JSONObject();
        userData.put("idCard",user.getResidentId());
        userData.put("name",user.getPersonName());
        userData.put("gender",user.getGender());
        userData.put("tel",user.getPersonPhone());
        userData.put("address","贵州省贵阳市");
        paramData.put("property",userData);
        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/databases/"+database_id+"/members", "POST", body);
        JSONObject resultJson = JSONObject.parseObject(resultData.toString());
        user.setThirdUserId(resultJson.getString("memberId"));
        return resultJson.getString("memberId");
    }

    @Override
    public void deleteThirdWorkerOrderUser() {
        //清空EVS数据
        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/databases/"+database_id+"/members/search?pageNo=1&pageSize=50"
            , "GET", null);
        JSONArray memList = JSONObject.parseObject(resultData.toString()).getJSONArray("data");
        for (Object o : memList) {
            Object resu = sendOkHttpClient(endpoint_ai+"v1/ai/databases/"+database_id+"/members?ids="
                    +JSONObject.parseObject(o.toString()).getString("memberId")
                , "DELETE", null);
        }
        //清空本地人员库信息
        workOrderUserService.getBaseMapper().delete(new LambdaQueryWrapper<>());
        return;
    }

    @Override
    public void getAiEventInfoData() {
        //拉取数据（最近一分钟的数据），进行本地存储
        Long start = LocalDateTime.now().minusHours(2).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        Long end = LocalDateTime.now().plusHours(2).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        LocalDateTime nowTime = LocalDateTime.now();
        System.out.println("时间======="+start+"======"+end);
        List<EvsHumanEvent> humanEvents = new LinkedList<>();
        //拉取人员布控AI事件列表
        Object humanData = sendOkHttpClient(endpoint_ai+"api/v2/ai/event/list?begin="
                +start+"&end="+end+"&maxSize=50&eventType=human_surveillance&appId="+human_app_id
            , "GET", null);
        if(humanData != null){
            JSONObject humanResultJson = JSONObject.parseObject(humanData.toString());
            JSONArray humanArray = JSONArray.parseArray(humanResultJson.getString("data"));
            if(humanArray.size() > 0){
                List<String> deviceIds = new LinkedList<>();
                for (Object o : humanArray) {
                    JSONObject dataJson = JSONObject.parseObject(o.toString());

                    String capTime = dataJson.getString("captureTime");
                    String eventId = dataJson.getString("eventId");
                    String channelId = dataJson.getString("channelId");
                    String appId = dataJson.getString("appId");
                    if(!StringUtils.equals(human_app_id,appId)){
                        continue;
                    }
                    long count = evsHumanEventService.getBaseMapper().selectCount(
                        new LambdaQueryWrapper<EvsHumanEvent>()
                            .eq(EvsHumanEvent::getEventId,eventId)
                            .gt(EvsHumanEvent::getCreatedTime,nowTime.minusMinutes(10))
                    );
                    if(count > 0){
                        continue;
                    }
                    deviceIds.add(channelId);
                    //拉取AI事件详情
                    Object humanDetailData = sendOkHttpClient(endpoint_ai+"api/v2/ai/event/result/list?eventId="+eventId+"&maxSize=90&eventType=human_surveillance"
                        , "GET", null);
                    JSONObject humanDetailResultJson = JSONObject.parseObject(humanDetailData.toString());
                    JSONArray humanDetailArray = JSONArray.parseArray(humanDetailResultJson.getString("data"));
                    if(humanDetailArray.size() > 0){
                        JSONObject detailJson = JSONObject.parseObject(humanDetailArray.get(humanDetailArray.size()-1).toString());

                        long detailCount = evsHumanEventService.getBaseMapper().selectCount(
                            new LambdaQueryWrapper<EvsHumanEvent>()
                                .eq(EvsHumanEvent::getEventId,eventId)
                                .eq(EvsHumanEvent::getCaptureTime,detailJson.getString("captureTime"))
                        );
                        if(detailCount > 0){
                            continue;
                        }

                        //人员布控
                        EvsHumanEvent humanEvent = new EvsHumanEvent();
                        humanEvent.setEventId(eventId);
                        humanEvent.setEventType(dataJson.getString("eventType"));
                        humanEvent.setAppId(dataJson.getString("appId"));
                        humanEvent.setCaptureTime(detailJson.getString("captureTime"));
                        humanEvent.setChannelId(dataJson.getString("channelId"));
                        humanEvent.setPicUrl(detailJson.getString("thumbnailUrl"));
                        humanEvent.setPunishType(dataJson.getString("punishType"));
                        if(dataJson.getJSONObject("personnelDatabase") != null){
                            humanEvent.setPersonName(dataJson.getJSONObject("personnelDatabase").getString("name"));
                            humanEvent.setPersonPic(dataJson.getJSONObject("personnelDatabase").getString("picUrl"));
                        }
                        humanEvent.setCreatedTime(nowTime);

                        JSONArray eventArray = new JSONArray();
                        String backWidth = detailJson.getJSONObject("originImage").getString("width");
                        String backHeight = detailJson.getJSONObject("originImage").getString("height");
                        JSONArray detailArray = detailJson.getJSONObject("analysisResult").getJSONArray("items");
                        for (Object o1 : detailArray) {
                            JSONObject location = JSONObject.parseObject(o1.toString()).getJSONObject("location");
                            JSONObject eventDetail = new JSONObject();
                            eventDetail.put("backWidth",backWidth);
                            eventDetail.put("backHeight",backHeight);
                            eventDetail.put("left",location.getString("left"));
                            eventDetail.put("top",location.getString("top"));
                            eventDetail.put("width",location.getString("width"));
                            eventDetail.put("height",location.getString("height"));
                            eventArray.add(eventDetail);
                        }
                        humanEvent.setEventArray(eventArray);

                        humanEvents.add(humanEvent);
                    }
                }
            }
        }

        //拉取机柜开关门AI事件列表
        Object doorData = sendOkHttpClient(endpoint_ai+"api/v2/ai/event/list?begin="
                +start+"&end="+end+"&maxSize=50&eventType=open_door_abnormal_detection&appId="+door_app_id
            , "GET", null);
        if(doorData != null){
            JSONObject doorResultJson = JSONObject.parseObject(doorData.toString());
            JSONArray doorArray = JSONArray.parseArray(doorResultJson.getString("data"));
            if(doorArray.size() > 0){
                List<String> deviceIds = new LinkedList<>();
                for (Object o : doorArray) {
                    JSONObject dataJson = JSONObject.parseObject(o.toString());

                    String eventId = dataJson.getString("eventId");
                    String channelId = dataJson.getString("channelId");
                    if(StringUtils.isBlank(channelId)){
                        channelId = dataJson.getString("deviceId");
                    }
                    String eventStatus = dataJson.getString("eventStatus");
                    String appId = dataJson.getString("appId");

                    if(!StringUtils.equals(door_app_id,appId)){
                        continue;
                    }
                    long count = evsHumanEventService.getBaseMapper().selectCount(
                        new LambdaQueryWrapper<EvsHumanEvent>()
                        .eq(EvsHumanEvent::getEventId,eventId)
                        .gt(EvsHumanEvent::getCreatedTime,nowTime.minusMinutes(20))
                    );
                    if(count > 0){
                        continue;
                    }
                    deviceIds.add(channelId);
                    //拉取AI事件详情
                    Object doorDetailData = sendOkHttpClient(endpoint_ai+"api/v2/ai/event/result/list?eventId="+eventId+"&maxSize=90&eventType=open_door_abnormal_detection"
                        , "GET", null);

                    JSONObject doorDetailResultJson = JSONObject.parseObject(doorDetailData.toString());
                    JSONArray doorDetailArray = JSONArray.parseArray(doorDetailResultJson.getString("data"));
                    if(doorDetailArray.size() > 0){
                        JSONObject detailJson = JSONObject.parseObject(doorDetailArray.get(doorDetailArray.size()-1).toString());
                        String capTime = detailJson.getString("captureTime");
                        DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
                        ZonedDateTime zonedDateTime = ZonedDateTime.parse(capTime, formatter);
                        LocalDateTime localDateTime = zonedDateTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
                        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                        capTime = localDateTime.format(formatter1);

                        long detailCount = evsHumanEventService.getBaseMapper().selectCount(
                            new LambdaQueryWrapper<EvsHumanEvent>()
                                .eq(EvsHumanEvent::getEventId,eventId)
                                .eq(EvsHumanEvent::getCaptureTime,capTime)
                        );
                        if(detailCount > 0){
                            continue;
                        }

                        //jiguikaiguanmen
                        EvsHumanEvent humanEvent = new EvsHumanEvent();
                        humanEvent.setEventId(eventId);
                        humanEvent.setEventType(dataJson.getString("eventType"));
                        humanEvent.setAppId(dataJson.getString("appId"));
                        humanEvent.setCaptureTime(capTime);
                        humanEvent.setChannelId(channelId);
                        humanEvent.setPicUrl(detailJson.getString("thumbnailUrl"));
                        humanEvent.setCreatedTime(nowTime);

                        JSONArray eventArray = new JSONArray();
                        String backWidth = detailJson.getJSONObject("originImage").getString("width");
                        String backHeight = detailJson.getJSONObject("originImage").getString("height");
                        JSONArray detailArray = detailJson.getJSONArray("analysisResult");
                        for (Object o1 : detailArray) {
                            JSONObject location = JSONObject.parseObject(o1.toString()).getJSONObject("location");
                            JSONObject eventDetail = new JSONObject();
                            eventDetail.put("backWidth",backWidth);
                            eventDetail.put("backHeight",backHeight);
                            eventDetail.put("left",location.getString("left"));
                            eventDetail.put("top",location.getString("top"));
                            eventDetail.put("width",location.getString("width"));
                            eventDetail.put("height",location.getString("height"));
                            eventArray.add(eventDetail);
                        }
                        humanEvent.setEventArray(eventArray);

                        humanEvents.add(humanEvent);
                    }
                }
            }
        }

        if(humanEvents.size() > 0){
            evsHumanEventService.saveBatch(humanEvents);
        }
        //每次拉取完数据都做一次告警校验
        if(humanEvents.size() > 0){
            this.handleWorkOrderAiEvent(humanEvents);
        }
    }

    public void handleWorkOrderAiEvent(List<EvsHumanEvent> humanEvents) {
        /**
         * 工单告警规则：
         *
         * 开关门告警：收到EVS开关门事件推送就表示有告警
         * 非法入侵：（1）收到EVS人员布控事件推送，并且该人员不在工单名单库内
         *         （2）收到EVS人员布控事件推送，人员在工单名单库内，但是进入机房与工单机房不匹配
         * 非工单时间进入：收到EVS人员布控事件推送，人员在工单名单库内，并且进入机房与工单机房匹配，但是进出时间不匹配
         * 不告警：人员匹配，工单匹配，时间匹配
         */

        /**
         * 人员布控判断流程：
         *  获取AI布控事件，判断是否在名单库内：
         *      否 -> 非法入侵
         *      是 -> 判断当前人员是否有工单：
         *              否 -> 非法入侵
         *              是 -> 判断AI事件触发的位置是否是工单对应的机房：
         *                      否 -> 非法入侵
         *                      是 -> 判断是否是在工单时间段内触发的：
         *                              是 -> 不告警
         *                              否 -> 非工单时间进入
         */

        List<WorkOrderAlarm> orderAlarms = new LinkedList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter formatterSpe = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'");
        DateTimeFormatter formatterSpe1 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

        //获取所有处于监控状态的人员信息
        List<WorkOrderUser> orderUsers = workOrderUserService.getBaseMapper().selectList(
            new LambdaQueryWrapper<WorkOrderUser>()
                .eq(WorkOrderUser::getStatus,Constants.INT_1)
                .ne(WorkOrderUser::getThirdUserId,"")
                .isNotNull(WorkOrderUser::getThirdUserId)
        );
        Map<String,List<WorkOrderUser>> orderUserMap = orderUsers.stream().collect(Collectors.groupingBy(WorkOrderUser::getPersonName));

        //获取当前自然日内未触发告警的工单信息
        List<DicmWorkOrder> workOrders = dicmWorkOrderService.getBaseMapper().selectList(
            new LambdaQueryWrapper<DicmWorkOrder>()
//            .eq(DicmWorkOrder::getIsAlarm,Constants.INT_0)
            .ge(DicmWorkOrder::getCreatedTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN))
        );
        Map<Integer,List<DicmWorkOrder>> workOrderMap = workOrders.stream().collect(Collectors.groupingBy(DicmWorkOrder::getUserId));

        List<DicmWorkOrder> updateWorkOrders = new LinkedList<>();

        //判断人员布控是否触发告警
        for (EvsHumanEvent humanEvent : humanEvents) {
            DicmNvr dicmNvr = dicmNvrService.getBaseMapper().selectOne(
                new LambdaQueryWrapper<DicmNvr>()
                .eq(DicmNvr::getThirdDeviceId,humanEvent.getChannelId())
            );
            if(dicmNvr == null){
                continue;
            }
            //rtsp://admin:Hik12345+@10.194.221.4:554/Streaming/tracks/1
            //rtsp://admin:Hik12345+@10.194.221.7:554/Streaming/tracks/401?starttime=20230702T040000Z&endtime=20230702T050000Z
            LocalDateTime captureTime = LocalDateTime.parse(humanEvent.getCaptureTime(), formatter);

            //兼容服务器时间和相机时间不匹配的问题
//            captureTime = captureTime.plusSeconds(120);

            String rtspUrl = "rtsp://"+dicmNvr.getUserName()+":"+dicmNvr.getUserPassword()
                +"@"+dicmNvr.getNvrIp()+":554/Streaming/tracks/"+dicmNvr.getChanelNo()+"01"
                +"?starttime="+captureTime.minusSeconds(90).format(formatterSpe)
                +"&endtime="+captureTime.plusSeconds(90).format(formatterSpe);

            if(StringUtils.equals("open_door_abnormal_detection",humanEvent.getEventType())){
                System.out.println("机柜开关门告警");
                WorkOrderAlarm orderAlarm = new WorkOrderAlarm();
                orderAlarm.setEventResultId(humanEvent.getId().longValue());
                orderAlarm.setAlarmType(Constants.INT_1);
                orderAlarm.setDeviceId(dicmNvr.getNvrId());
                orderAlarm.setRtspUrl(rtspUrl);
                orderAlarm.setAlarmTime(captureTime);
                orderAlarm.setDicmNvr(dicmNvr);

                downloadAiEventPic(humanEvent);

                orderAlarm.setPicUrl(humanEvent.getPicUrl());
                orderAlarms.add(orderAlarm);

                continue;
            }

            if(StringUtils.isBlank(humanEvent.getPersonName())){
                //无布控人员信息，说明是非法入侵
                System.out.println("无布控人员信息---非法入侵");
                WorkOrderAlarm orderAlarm = new WorkOrderAlarm();
                orderAlarm.setEventResultId(humanEvent.getId().longValue());
                orderAlarm.setAlarmType(Constants.INT_2);
                orderAlarm.setDeviceId(dicmNvr.getNvrId());
                orderAlarm.setRtspUrl(rtspUrl);
                orderAlarm.setAlarmTime(captureTime);
                orderAlarm.setDicmNvr(dicmNvr);

                downloadAiEventPic(humanEvent);

                orderAlarm.setPicUrl(humanEvent.getPicUrl());
                orderAlarms.add(orderAlarm);
                continue;
            }
            if(StringUtils.equals("-",humanEvent.getPersonName()) && StringUtils.equals("-",humanEvent.getPersonPic())){
                //无布控人员信息，说明是非法入侵
                System.out.println("无布控人员信息---非法入侵");
                WorkOrderAlarm orderAlarm = new WorkOrderAlarm();
                orderAlarm.setEventResultId(humanEvent.getId().longValue());
                orderAlarm.setAlarmType(Constants.INT_2);
                orderAlarm.setDeviceId(dicmNvr.getNvrId());
                orderAlarm.setRtspUrl(rtspUrl);
                orderAlarm.setAlarmTime(captureTime);
                orderAlarm.setDicmNvr(dicmNvr);

                downloadAiEventPic(humanEvent);

                orderAlarm.setPicUrl(humanEvent.getPicUrl());
                orderAlarms.add(orderAlarm);
                continue;
            }
            if(orderUserMap.get(humanEvent.getPersonName()) == null){
                //布控人员不在名单库内，非法入侵
                System.out.println("布控人员不在名单库内---非法入侵");
                WorkOrderAlarm orderAlarm = new WorkOrderAlarm();
                orderAlarm.setEventResultId(humanEvent.getId().longValue());
                orderAlarm.setAlarmType(Constants.INT_2);
                orderAlarm.setDeviceId(dicmNvr.getNvrId());
                orderAlarm.setRtspUrl(rtspUrl);
                orderAlarm.setAlarmTime(captureTime);
                orderAlarm.setDicmNvr(dicmNvr);

                downloadAiEventPic(humanEvent);

                orderAlarm.setPicUrl(humanEvent.getPicUrl());
                orderAlarms.add(orderAlarm);
                continue;
            }
            WorkOrderUser workOrderUser = orderUserMap.get(humanEvent.getPersonName()).get(0);
            if(workOrderMap.get(workOrderUser.getUserId()) == null){
                //布控人员没有工单，非法入侵
                System.out.println("布控人员没有工单---非法入侵");
                WorkOrderAlarm orderAlarm = new WorkOrderAlarm();
                orderAlarm.setEventResultId(humanEvent.getId().longValue());
                orderAlarm.setAlarmType(Constants.INT_2);
                orderAlarm.setDeviceId(dicmNvr.getNvrId());
                orderAlarm.setRtspUrl(rtspUrl);
                orderAlarm.setAlarmTime(captureTime);
                orderAlarm.setDicmNvr(dicmNvr);

                downloadAiEventPic(humanEvent);

                orderAlarm.setPicUrl(humanEvent.getPicUrl());
                orderAlarms.add(orderAlarm);
                continue;
            }
            List<DicmWorkOrder> userWorkOrders = workOrderMap.get(workOrderUser.getUserId());
            List<DicmWorkOrder> checkWorkOrders = new LinkedList<>();
            for (DicmWorkOrder userWorkOrder : userWorkOrders) {
                if(StringUtils.equals(userWorkOrder.getRoomNum(),dicmNvr.getAddressId())){
                    if(StringUtils.isBlank(userWorkOrder.getChannelNum())){
                        checkWorkOrders.add(userWorkOrder);
                        continue;
                    }
                    //有通道信息的情况下，只有机房ID和通道号能匹配上才算匹配成功
                    String[] channelArray = userWorkOrder.getChannelNum().split(",");
                    Boolean checkSuccess = false;
                    for (String channelNum : channelArray) {
                        if(dicmNvr.getNvrName().indexOf(channelNum) > -1){
                            checkSuccess = true;
                        }
                    }
                    if(checkSuccess){
                        checkWorkOrders.add(userWorkOrder);
                    }
                }
            }
            if(checkWorkOrders.size() == 0){
                //所有工单的进入机房都不匹配，非法入侵
                System.out.println("所有工单的进入机房都不匹配---非法入侵");
                WorkOrderAlarm orderAlarm = new WorkOrderAlarm();
                orderAlarm.setEventResultId(humanEvent.getId().longValue());
                orderAlarm.setAlarmType(Constants.INT_2);
                orderAlarm.setDeviceId(dicmNvr.getNvrId());
                orderAlarm.setRtspUrl(rtspUrl);
                orderAlarm.setAlarmTime(captureTime);
                orderAlarm.setDicmNvr(dicmNvr);

                downloadAiEventPic(humanEvent);

                orderAlarm.setPicUrl(humanEvent.getPicUrl());
                orderAlarms.add(orderAlarm);
                continue;
            }
            Boolean checkStatus = false;
            for (DicmWorkOrder checkWorkOrder : checkWorkOrders) {
                LocalDateTime startTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(
                    Long.parseLong(checkWorkOrder.getEarliestEnterTime())), ZoneId.systemDefault());
                LocalDateTime endTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(
                    Long.parseLong(checkWorkOrder.getLatestEnterTime())), ZoneId.systemDefault());
                if(captureTime.isAfter(startTime) && captureTime.isBefore(endTime)){
                    checkWorkOrder.setIsAlarm(Constants.INT_1);
                    updateWorkOrders.add(checkWorkOrder);
                    checkStatus = true;
                }
            }
            if(!checkStatus){
                //工单进入时间不匹配，非工单时间进入
                System.out.println("工单进入时间不匹配---非法入侵");
                WorkOrderAlarm orderAlarm = new WorkOrderAlarm();
                orderAlarm.setEventResultId(humanEvent.getId().longValue());
                orderAlarm.setAlarmType(Constants.INT_3);
                orderAlarm.setDeviceId(dicmNvr.getNvrId());
                orderAlarm.setRtspUrl(rtspUrl);
                orderAlarm.setAlarmTime(captureTime);
                orderAlarm.setOrderId(checkWorkOrders.get(0).getOrderId());
                orderAlarm.setDicmNvr(dicmNvr);
                downloadAiEventPic(humanEvent);
                orderAlarm.setPicUrl(humanEvent.getPicUrl());
                orderAlarm.setWorkOrder(checkWorkOrders.get(0));

                orderAlarms.add(orderAlarm);
            }
        }
        if(orderAlarms.size() > 0){
            workOrderAlarmService.saveBatch(orderAlarms);
            //将告警数据推送给dicm
            for (WorkOrderAlarm orderAlarm : orderAlarms) {
                DicmNvr dicmNvr = orderAlarm.getDicmNvr();
                DicmWorkOrder workOrder = orderAlarm.getWorkOrder();

                JSONObject dataJson = new JSONObject();
                dataJson.put("alarmId",orderAlarm.getAlarmId());
                dataJson.put("orderId",orderAlarm.getOrderId());
                dataJson.put("alarmType",orderAlarm.getAlarmType());
                dataJson.put("deviceId",orderAlarm.getDeviceId());
                dataJson.put("rtspUrl",orderAlarm.getRtspUrl());
                dataJson.put("alarmTime",orderAlarm.getAlarmTime());
                dataJson.put("nvrName",dicmNvr.getNvrName());

                //拼接告警位置
                DicmAddress address = dicmAddressService.getBaseMapper().selectById(dicmNvr.getAddressId());
                dataJson.put("addressName",address.getAddressName()+"-"+dicmNvr.getNvrName().substring(0,5));

                if(workOrder != null){
                    dataJson.put("personName",workOrder.getPersonName());
                    dataJson.put("personPhone",workOrder.getPersonPhone());
                    dataJson.put("residentId",workOrder.getResidentId());
                    dataJson.put("badgeNum",workOrder.getBadgeNum());
                    dataJson.put("earliestEnterTime",workOrder.getEarliestEnterTime());
                    dataJson.put("latestEnterTime",workOrder.getLatestEnterTime());
                }
                dataJson.put("picUrl",orderAlarm.getPicUrl());
                dataJson.put("alarmLevel",orderAlarm.getAlarmType().intValue() == 1 ?
                    "三级" : (orderAlarm.getAlarmType().intValue() == 2 ? "一级" : "二级")
                );

                Object jsonObject = HttpUtils.sendJsonPostRequest(ApiConstants.IP_ADDRESS + ApiConstants.WORK_ORDER_ALARM_SEND,dataJson.toJSONString());
                System.out.println("工单告警推送结果："+jsonObject);
            }
        }
        if(updateWorkOrders.size() > 0){
            dicmWorkOrderService.saveOrUpdateBatch(updateWorkOrders);
        }
    }

    /**
     * 图片信息本地存储
     * @param humanEvent
     * @throws MalformedURLException
     */
    public void downloadAiEventPic(EvsHumanEvent humanEvent){
        String picUrl = humanEvent.getPicUrl();
        if(StringUtils.isBlank(picUrl)){
            return;
        }
        try {
            URL url = new URL(picUrl);
            BufferedInputStream inputStream = new BufferedInputStream(url.openStream());

            // 读取图片
            BufferedImage originalImage = ImageIO.read(inputStream);
            for (Object o : humanEvent.getEventArray()) {
                JSONObject detailJson = JSONObject.parseObject(o.toString());

                BigDecimal oriWidth = new BigDecimal(String.valueOf(originalImage.getWidth()));
                BigDecimal oriHeight = new BigDecimal(String.valueOf(originalImage.getHeight()));
                BigDecimal falWidth = new BigDecimal(detailJson.getString("backWidth"));
                BigDecimal falHeight = new BigDecimal(detailJson.getString("backHeight"));
                Graphics2D g2d = originalImage.createGraphics();
                g2d.setColor(Color.red);
                // 在指定区域画透明红框
                int x = (new BigDecimal(detailJson.getString("left"))
                    .multiply(oriWidth).divide(falWidth,0, BigDecimal.ROUND_HALF_UP)).intValue();
                int y = (new BigDecimal(detailJson.getString("top"))
                    .multiply(oriHeight).divide(falHeight,0, BigDecimal.ROUND_HALF_UP)).intValue();
                int width = (new BigDecimal(detailJson.getString("width"))
                    .multiply(oriWidth).divide(falWidth,0, BigDecimal.ROUND_HALF_UP)).intValue();
                int height = (new BigDecimal(detailJson.getString("height"))
                    .multiply(oriHeight).divide(falHeight,0, BigDecimal.ROUND_HALF_UP)).intValue();
                g2d.drawRect(x, y, width, height);
                g2d.dispose();
            }

            String filePath = (LocalDate.now()+"/"+humanEvent.getId()+"-"+System.currentTimeMillis()+".png");
            File dateFile = new File("/home/guian_storage/fileInfo/"+LocalDate.now());
            if(!dateFile.exists()){
                dateFile.mkdirs();
            }
            // 保存修改后的图片
            ImageIO.write(originalImage, "jpg", new File("/home/guian_storage/fileInfo/"+filePath));
            picUrl = ("http://10.195.216.12:8088/fileInfo/"+filePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        humanEvent.setPicUrl(picUrl);
        evsHumanEventService.getBaseMapper().updateById(humanEvent);
        return;
    }

    @Override
    public R evsDeviceRegister(DicmNvrRegisterDto dto) {
        //注册设备
        List<DicmNvr> nvrList = dicmNvrService.getBaseMapper().selectList(
            new LambdaQueryWrapper<DicmNvr>()
                .eq(StringUtils.isNotBlank(dto.getAddressId()),DicmNvr::getAddressId,dto.getAddressId())
                .eq(StringUtils.isNotBlank(dto.getNvrId()),DicmNvr::getNvrId,dto.getNvrId())
                .eq(DicmNvr::getStatus,Constants.INT_0)
        );
        int successCount = 0;
        List<String> deviceIds = new LinkedList<>();
        for (DicmNvr dicmNvr : nvrList) {
            JSONObject paramData = new JSONObject();
            paramData.put("spaceId",dto.getSpaceId());
            paramData.put("deviceName",StringUtils.removeInvalidCharacters(dicmNvr.getNvrName())+"-"+dicmNvr.getNvrId());
            paramData.put("type","RTSP");
            paramData.put("description",dicmNvr.getNvrName()+"-"+dicmNvr.getNvrId());
            JSONObject paramDataNvr = new JSONObject();
            paramDataNvr.put("username",dicmNvr.getUserName());
            paramDataNvr.put("password", dicmNvr.getUserPassword());
            paramDataNvr.put("rtspUri", "rtsp://"+dicmNvr.getUserName()+":"+dicmNvr.getUserPassword()
                +"@"+dicmNvr.getNvrIp()+":554/Streaming/Channels/"+dicmNvr.getChanelNo()+"01");
            paramData.put("rtspConfig",paramDataNvr);
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
            Object dicmNvrResultData = sendOkHttpClient(endpoint +"v1/device", "POST", body);
            if(dicmNvrResultData == null){
                continue;
            }
            //            {"deviceId":1061397}
            String deviceId = JSONObject.parseObject(dicmNvrResultData.toString()).getString("deviceId");
            if(StringUtils.isNotBlank(deviceId)){
                dicmNvr.setThirdDeviceId(deviceId);
                deviceIds.add(deviceId);
            }
            successCount ++;
        }
        dicmNvrService.saveOrUpdateBatch(nvrList);

        if(deviceIds.size() > 0){
            //绑定设备到应用
            JSONObject paramData = new JSONObject();
            paramData.put("channelIds",deviceIds.toArray());
            RequestBody body123 = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
            Object bindResultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+dto.getAppId()+"/channels/bind", "POST", body123);
        }

        return R.ok(successCount);
    }

    @Override
    public R getEvsEvent() {
        //拉取数据（最近一分钟的数据），进行本地存储
        Instant instant1 = LocalDateTime.now().atZone(ZoneOffset.UTC).toInstant();
        Instant instant2 = LocalDateTime.now().minusDays(3).atZone(ZoneOffset.UTC).toInstant();
        Long start = instant2.toEpochMilli();
        Long end = instant1.toEpochMilli();
        LocalDateTime nowTime = LocalDateTime.now();

        //拉取AI事件
        Object resultData = sendOkHttpClient(endpoint_ai + "v1/ai/event/list?begin="+start+"&end="+end+"&maxSize=90"
            , "GET", null);
        logger.error("resultData==========="+resultData);
        JSONObject resultJson = JSONObject.parseObject(resultData.toString());
        JSONArray dataArray = JSONArray.parseArray(resultJson.getString("data"));
        List<EvsHumanEvent> humanEvents = new LinkedList<>();
        List<EvsDoorEvent> doorEvents = new LinkedList<>();
        for (Object o : dataArray) {
            JSONObject dataJson = JSONObject.parseObject(o.toString());
            String eventType = dataJson.getString("eventType");
            if(StringUtils.equals("human_surveillance",eventType)){
                //人员布控
                EvsHumanEvent humanEvent = new EvsHumanEvent();
                humanEvent.setEventId(dataJson.getString("eventId"));
                humanEvent.setEventType(dataJson.getString("eventType"));
                humanEvent.setAppId(dataJson.getString("appId"));
                humanEvent.setCaptureTime(dataJson.getString("captureTime"));
                humanEvent.setChannelId(dataJson.getString("channelId"));
                humanEvent.setPicUrl(dataJson.getString("picUrl"));
                humanEvent.setPunishType(dataJson.getString("punishType"));
                if(dataJson.getJSONObject("personnelDatabase") != null){
                    humanEvent.setPersonName(dataJson.getJSONObject("personnelDatabase").getString("name"));
                    humanEvent.setPersonPic(dataJson.getJSONObject("personnelDatabase").getString("picUrl"));
                }
                humanEvent.setCreatedTime(nowTime);
                humanEvents.add(humanEvent);
            }else if(StringUtils.equals("open_door_abnormal_detection",eventType)){
                //开关门检测
                EvsDoorEvent doorEvent = new EvsDoorEvent();
                doorEvent.setEventId(dataJson.getString("eventId"));
                doorEvent.setEventType(dataJson.getString("eventType"));
                doorEvent.setAppId(dataJson.getString("appId"));
                doorEvent.setDeviceId(dataJson.getString("deviceId"));
                doorEvent.setChannelId(dataJson.getString("channelId"));
                doorEvent.setEventStatus(dataJson.getString("eventStatus"));
                doorEvent.setStartTime(dataJson.getString("startTime"));
                doorEvent.setEndTime(dataJson.getString("endTime"));
                doorEvent.setFirstPicUrl(dataJson.getString("firstPicUrl"));
                doorEvent.setCreatedTime(nowTime);
                doorEvents.add(doorEvent);
            }
        }
        if(humanEvents.size() > 0){
            evsHumanEventService.saveBatch(humanEvents);
        }
        if(doorEvents.size() > 0){
            evsDoorEventService.saveBatch(doorEvents);
        }
        return R.ok(humanEvents);
    }



    @Override
    public void updateAiApp() {
//        String s = "{\"detectAreas\":[{\"sides\":[{\"startPointX\":0,\"startPointY\":49,\"endPointX\":47,\"endPointY\":7}" +
//            ",{\"startPointX\":47,\"startPointY\":7,\"endPointX\":48,\"endPointY\":27}" +
//            ",{\"startPointX\":48,\"startPointY\":27,\"endPointX\":54,\"endPointY\":27}" +
//            ",{\"startPointX\":54,\"startPointY\":27,\"endPointX\":54,\"endPointY\":8}," +
//            "{\"startPointX\":54,\"startPointY\":8,\"endPointX\":100,\"endPointY\":51}," +
//            "{\"startPointX\":100,\"startPointY\":51,\"endPointX\":86,\"endPointY\":99}," +
//            "{\"startPointX\":86,\"startPointY\":99,\"endPointX\":15,\"endPointY\":99}," +
//            "{\"startPointX\":15,\"startPointY\":99,\"endPointX\":15,\"endPointY\":98}," +
//            "{\"startPointX\":15,\"startPointY\":98,\"endPointX\":0,\"endPointY\":49}]," +
//            "\"type\":\"POLYGON\",\"name\":\"绘制区域1\",\"subType\":\"DETECT\"}]}";
//
//
//        List<String> list = new LinkedList<>();
//        list.add("1000017");
//        list.add("1000018");
//        list.add("1000019");
//        list.add("1000020");
//        list.add("1000021");
//        list.add("1000022");
//        list.add("1000023");
//        list.add("1000024");
//
//        for (String s1 : list) {
//            JSONObject openParamData1 = JSONObject.parseObject(s);
//            RequestBody body1 = RequestBody.create(MediaType.parse("application/json"), openParamData1.toJSONString());
//            sendOkHttpClient(endpoint_ai+"/v1/ai/apps/"+door_app_id+"/channels/"+s1+"/detect_area", "PUT", body1);
//        }


        String s = "{\n" +
            "  \"type\": \"human_surveillance\", \n" +
            "  \"punishType\": \"remind\"," +
            "  \"databaseIds\": [\""+database_id+"\"], " +
            "  \"confidence\": 0.6, " +
            "  \"duration\": 1800000," +
            "  \"effectiveTime\": { " +
            "        \"type\": \"WEEK\",\n" +
            "        \"timePeriods\": [\n" +
            "            {\n" +
            "                \"startTime\": \"00:00:00\",\n" +
            "                \"endTime\": \"23:59:59\",\n" +
            "                \"dayInWeek\": 1 " +
            "            },\n" +
            "            {\n" +
            "                \"startTime\": \"00:00:00\",\n" +
            "                \"endTime\": \"23:59:59\",\n" +
            "                \"dayInWeek\": 2 " +
            "            },\n" +
            "            {\n" +
            "                \"startTime\": \"00:00:00\",\n" +
            "                \"endTime\": \"23:59:59\",\n" +
            "                \"dayInWeek\": 3 " +
            "            },\n" +
            "            {\n" +
            "                \"startTime\": \"00:00:00\",\n" +
            "                \"endTime\": \"23:59:59\",\n" +
            "                \"dayInWeek\": 4 " +
            "            },\n" +
            "            {\n" +
            "                \"startTime\": \"00:00:00\",\n" +
            "                \"endTime\": \"23:59:59\",\n" +
            "                \"dayInWeek\": 5 " +
            "            },\n" +
            "            {\n" +
            "                \"startTime\": \"00:00:00\",\n" +
            "                \"endTime\": \"23:59:59\",\n" +
            "                \"dayInWeek\": 6 " +
            "            },\n" +
            "            {\n" +
            "                \"startTime\": \"00:00:00\",\n" +
            "                \"endTime\": \"23:59:59\",\n" +
            "                \"dayInWeek\": 7 " +
            "            }\n" +
            "        ]\n" +
            "    }\n" +
            "}\n";
        JSONObject paramData = JSONObject.parseObject(s);
        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+human_app_id+"/config/human_surveillance", "PUT", body);
    }

    @Override
    public void checkAiDeviceStatus() {
        //获取异常设备列表
        Object resultData = sendOkHttpClient(endpoint
            +"v1/device?pageNo=1&pageSize=50&spaceId="+space_id+"&status=DEAD", "GET", null);
        if(resultData == null){
            return;
        }
        JSONArray deviceArray = JSONArray.parseArray(JSONObject.parseObject(resultData.toString()).getString("data"));
        if(deviceArray.size() == 0){
            return;
        }
        for (Object o : deviceArray) {
            JSONObject jsonObject = JSONObject.parseObject(o.toString());
            String deviceId = jsonObject.getString("deviceId");
            //设备异常重试
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), "{}");
            sendOkHttpClient(endpoint+"v1/device/onvif/"+deviceId+"?retry", "PUT", body);
        }
    }

    @Override
    public void getSeatMessageData() {
        //查询所有房间信息ID
        List<String> addressIdList = dicmAddressService.queryAddressIdList();
        if (CollectionUtil.isNotEmpty(addressIdList)){
            addressIdList.forEach(item -> {
                List<PostureDevice> saveList = new ArrayList<>();
                //获取U信息
                JSONObject jsonObject = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
                    +ApiConstants.DEVICE_MESSAGE_URL+item);
                if (null != jsonObject){
                    List<SeatMessageVo> seatMessageList = JSONUtil.toList(JSONUtil.parseArray(jsonObject), SeatMessageVo.class);
                    if (CollectionUtil.isNotEmpty(seatMessageList.get(0).getSeat())){
                        List<SeatVo> seatList = seatMessageList.get(0).getSeat();
                        seatList.forEach(value -> {
                            if (CollectionUtil.isNotEmpty(value.getChildren())){
                                value.getChildren().forEach(children -> {
                                    PostureDevice postureDevice = new PostureDevice();
                                    postureDevice.setName(children.getResName());
                                    postureDevice.setCabinetNum(value.getSeatCode());
                                    postureDevice.setLocation(Integer.getInteger(children.getPosition()));
                                    postureDevice.setHeight(children.getHeight());
                                    postureDevice.setWmfNo(item);
                                    postureDevice.setCreateTime(LocalDateTime.now());
                                    postureDevice.setUpdateTime(LocalDateTime.now());
                                    saveList.add(postureDevice);
                                });
                            }
                        });
                    }
                }
                postureDeviceService.addDevice(saveList);
            });
        }
    }

    @Override
    public void getAssetsMessage() {
        JSONObject resultData = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
            +ApiConstants.DEVICE_MESSAGE_URL);
        logger.info("获取资产数据:{}"+resultData);
        if (null != resultData) {
            List<DicmAddress> addressesList = new ArrayList<>();
            List<DicmNvr> nvrList = new ArrayList<>();
            List<DicmDevice> deviceList = new ArrayList<>();
            List<PostureDevice> postureDeviceList = new ArrayList<>();
            List<DicmCabinet> cabinetList = new ArrayList<>();
            List<AssetsMessageVo> assetsMessageList = JSONUtil.toList(JSONUtil.parseArray(resultData.get("data")), AssetsMessageVo.class);
            getDicmAddressMessage(assetsMessageList,addressesList,nvrList,postureDeviceList,deviceList,assetsMessageList.get(0).getParentId(),cabinetList);

            if (CollectionUtil.isNotEmpty(addressesList)){
                dicmAddressService.saveDicmAddress(addressesList);
            }

            if (CollectionUtil.isNotEmpty(cabinetList)){
                dicmCabinetService.savecabinetList(cabinetList);
                List<String> parentIdList = cabinetList.stream().map(DicmCabinet::getParentId).collect(Collectors.toList());
                List<String> list = parentIdList.stream().distinct().collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(list)){
                    list.forEach(item -> {
                        JSONObject cabinetJson = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
                            +ApiConstants.CABINET_URL+"?roomId="+item);
                        if (null != cabinetJson){
                            List<QueryPostureDeviceDto> postureList = JSONUtil.toList(JSONUtil.parseArray(cabinetJson.get("data")), QueryPostureDeviceDto.class);
                            if (CollectionUtil.isNotEmpty(postureList)){
                                postureList.forEach(value -> {
                                    postureDeviceNewService.savePostureDevice(value.getSeat(),item);
                                });
                            }

                        }
                    });
                }
            }

            if (CollectionUtil.isNotEmpty(deviceList)){
                dicmDeviceService.addDevice(deviceList);
            }

            if (CollectionUtil.isNotEmpty(nvrList)){
                dicmNvrService.saveDicnNvrList(nvrList);
            }
        }
    }

    @Override
    public void savePostureDevice(List<QueryPostureDeviceDto> postureList) {
        if (CollectionUtil.isNotEmpty(postureList)){
            postureList.forEach(value -> {
                postureDeviceNewService.savePostureDevice(value.getSeat(),"00001005050000000120");
            });
        }
    }

    @Override
    public void getAssetsMessage1(JSONObject resultData) {
//        JSONObject resultData = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
//            +ApiConstants.DEVICE_MESSAGE_URL);
        if (null != resultData) {
            List<DicmAddress> addressesList = new ArrayList<>();
            List<DicmNvr> nvrList = new ArrayList<>();
            List<DicmDevice> deviceList = new ArrayList<>();
            List<PostureDevice> postureDeviceList = new ArrayList<>();
            List<DicmCabinet> cabinetList = new ArrayList<>();
            List<AssetsMessageVo> assetsMessageList = JSONUtil.toList(JSONUtil.parseArray(resultData.get("data")), AssetsMessageVo.class);
            getDicmAddressMessage(assetsMessageList,addressesList,nvrList,postureDeviceList,deviceList,assetsMessageList.get(0).getParentId(),cabinetList);

            if (CollectionUtil.isNotEmpty(addressesList)){
                dicmAddressService.saveDicmAddress(addressesList);
            }

            if (CollectionUtil.isNotEmpty(cabinetList)){
                dicmCabinetService.savecabinetList(cabinetList);
                List<String> parentIdList = cabinetList.stream().map(DicmCabinet::getParentId).collect(Collectors.toList());
                List<String> list = parentIdList.stream().distinct().collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(list)){
                    list.forEach(item -> {
                        JSONObject cabinetJson = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
                            +ApiConstants.CABINET_URL+"?roomId="+item);
                        logger.info("获取u信息："+cabinetJson);
                        if (null != cabinetJson){
                            List<DicmPostureDeviceDto> postureList = JSONUtil.toList(JSONUtil.parseArray(cabinetJson.get("data")), DicmPostureDeviceDto.class);
                            postureDeviceNewService.savePostureDevice(postureList,item);
                        }
                    });
                }
            }

            if (CollectionUtil.isNotEmpty(deviceList)){
                dicmDeviceService.addDevice(deviceList);
            }

            if (CollectionUtil.isNotEmpty(nvrList)){
                dicmNvrService.saveDicnNvrList(nvrList);
            }
        }
    }



    public void getDicmAddressMessage(List<AssetsMessageVo> assetsMessageList,List<DicmAddress> addressesList,List<DicmNvr> nvrList,List<PostureDevice> postureDeviceList,List<DicmDevice> deviceList,String parentId,List<DicmCabinet> cabinetList){
        for (AssetsMessageVo assetsMessageVo : assetsMessageList) {
            if (StringUtils.isNotEmpty(assetsMessageVo.getParentId()) && StringUtils.isNotEmpty(assetsMessageVo.getId()))
                parentId = assetsMessageVo.getId();
            if (StringUtils.isNotEmpty(assetsMessageVo.getName()) && "摄像头".equals(assetsMessageVo.getName())){
                assetsMessageVo.getChildrens().forEach(value -> {
                    if (StringUtils.isNotEmpty(value.getData())){
                        Map<String,Object> map = JSONUtil.toBean(value.getData(), Map.class);
                        DicmNvr dicmNvr = new DicmNvr();
                        dicmNvr.setThirdDeviceId((String)map.get("deviceTypeId"));
                        dicmNvr.setAddressId((String)map.get("addressId"));
                        dicmNvr.setNvrName((String)map.get("name"));
                        dicmNvr.setBrand((String)map.get("vendor"));
                        Object obj = map.get("channelId");
                        if (StringUtils.isNotEmpty(obj.toString())){
                            dicmNvr.setChanelNo(obj.toString());
                        }
                        dicmNvr.setNvrIp((String)map.get("nvrIp"));
                        dicmNvr.setUserName((String)map.get("user"));
                        dicmNvr.setUserPassword((String)map.get("password"));
                        if (StringUtils.isNotEmpty((String)map.get("status"))) {
                            dicmNvr.setStatus(Integer.parseInt((String)map.get("status")));
                        }
                        dicmNvr.setRtspUrl((String)map.get("rtsp"));
                        nvrList.add(dicmNvr);
                    }
                });
            }else if (StringUtils.isNotEmpty(assetsMessageVo.getName()) && "机柜".equals(assetsMessageVo.getName())){
                for (AssetsMessageVo children : assetsMessageVo.getChildrens()) {
                    DicmCabinet dicmCabinet = new DicmCabinet();
                    dicmCabinet.setAddressId(children.getId());
                    dicmCabinet.setCabinetName(children.getName());
                    dicmCabinet.setDeviceId(children.getDeviceId());
                    dicmCabinet.setUsum(children.getUsum());
                    dicmCabinet.setParentId(parentId);
//                    DicmAddress dicmAddress = new DicmAddress();
//                    dicmAddress.setAddressId(children.getId());
//                    dicmAddress.setAddressName(children.getName());
//                    dicmAddress.setParentId(parentId);
//                    dicmAddress.setAddressType(0);
//                    dicmAddress.setStatus(0);
//                    dicmAddress.setAddressType(children.getLevel());
//                    dicmAddress.setDeviceId(children.getDeviceId());
//                    dicmAddress.setDeviceName(children.getDeviceName());
//                    dicmAddress.setDeviceTypeId(children.getDeviceTypeId());
//                    dicmAddress.setDeviceTypeName(children.getDeviceTypeName());
                    cabinetList.add(dicmCabinet);
                }
            }else if (StringUtils.isNotEmpty(assetsMessageVo.getName()) && "设备".equals(assetsMessageVo.getName())){
                for (AssetsMessageVo children : assetsMessageVo.getChildrens()) {
                    DicmDevice dicmDevice = new DicmDevice();
                    dicmDevice.setDeviceId(children.getDeviceId());
                    dicmDevice.setAddressId(parentId);
                    dicmDevice.setDeviceName(children.getDeviceName());
                    if (StringUtils.isNotEmpty(children.getDeviceTypeId())) {
                        dicmDevice.setDeviceType(Integer.parseInt(children.getDeviceTypeId()));
                    }
                    deviceList.add(dicmDevice);
                }
            } else {
                DicmAddress dicmAddress = new DicmAddress();
                dicmAddress.setAddressId(assetsMessageVo.getId());
                dicmAddress.setAddressName(assetsMessageVo.getName());
                dicmAddress.setParentId(assetsMessageVo.getParentId());
                dicmAddress.setAddressType(0);
                dicmAddress.setStatus(0);
                dicmAddress.setAddressType(assetsMessageVo.getLevel());
                dicmAddress.setDeviceId(assetsMessageVo.getDeviceId());
                dicmAddress.setDeviceName(assetsMessageVo.getDeviceName());
                dicmAddress.setDeviceTypeId(assetsMessageVo.getDeviceTypeId());
                dicmAddress.setDeviceTypeName(assetsMessageVo.getDeviceTypeName());
                addressesList.add(dicmAddress);
            }

            if (CollectionUtil.isEmpty(assetsMessageVo.getChildrens())){
                return;
            }else {
                getDicmAddressMessage(assetsMessageVo.getChildrens(),addressesList,nvrList,postureDeviceList,deviceList,parentId,cabinetList);
            }
        }
    }


    @Override
    public void getEnergyEfficiency() {
        List<DicmAddressData> dicmAddressDataList = new ArrayList<>();
        //获取U信息
        JSONObject jsonObject = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
            +ApiConstants.BLADE_ENERGY);
        logger.info("获取pue信息返回结果：{}"+JSONUtil.parse(jsonObject));
        if (null != jsonObject){
            String data = JSON.toJSONString(jsonObject.get("data"));
            Map<String,Object> map = JSONUtil.toBean(data, Map.class);
            if (CollectionUtil.isNotEmpty(map)){
                map.forEach((key,value) -> {
                    DicmAddressData dicmAddressData = new DicmAddressData();
                    dicmAddressData.setAddressName(key);
                    dicmAddressData.setAddressNumber(null != value ? value.toString() : "0");
                    dicmAddressData.setCreateTime(new Date());
                    dicmAddressDataList.add(dicmAddressData);
                });
            }
        }
        dicmAddressDataService.saveBatch(dicmAddressDataList);
    }


    @Override
    public void getEvsDeviceId() {
        List<DicmNvr> dicmNvrList = dicmNvrService.queryNvrList();
        dicmNvrList.forEach(item -> {
            List<String> deviceIds = new LinkedList<>();
            JSONObject paramData = new JSONObject();
            paramData.put("spaceId",space_id);
            paramData.put("deviceName",StringUtils.removeInvalidCharacters(item.getNvrName())+"-"+item.getNvrId());
            paramData.put("type","RTSP");
            paramData.put("description",item.getNvrName()+"-"+item.getNvrId());
            JSONObject paramDataNvr = new JSONObject();
            paramDataNvr.put("username",item.getUserName());
            paramDataNvr.put("password", item.getUserPassword());
            paramDataNvr.put("rtspUri", "rtsp://"+item.getUserName()+":"+item.getUserPassword()
                +"@"+item.getNvrIp()+":554/Streaming/Channels/"+item.getChanelNo()+"01");
            paramData.put("rtspConfig",paramDataNvr);
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
            Object dicmNvrResultData = sendOkHttpClient(endpoint +"v1/device", "POST", body);
            if(dicmNvrResultData != null){
                //            {"deviceId":1061397}
                String deviceId = JSONObject.parseObject(dicmNvrResultData.toString()).getString("deviceId");
                if (org.apache.commons.lang.StringUtils.isNotBlank(deviceId)){
                    item.setThirdDeviceId(deviceId);
                    deviceIds.add(deviceId);
                    //绑定设备到应用
                    JSONObject paramData1 = new JSONObject();
                    paramData.put("channelIds",deviceIds.toArray());
                    RequestBody body123 = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
                    Object bindResultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+human_app_id+"/channels/bind", "POST", body123);
                    Object bindResultData1 = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+door_app_id+"/channels/bind", "POST", body123);
                }
            }
        });

        dicmNvrService.updateNvrById(dicmNvrList);
    }

    @Override
    public void unbindAll() {
        //查询所有绑定设备ID
        List<String> deviceId =  dicmNvrService.queryDeviceId();
        List<String> list = dicmNvrService.queryNvrDeviceId();
        if (CollectionUtil.isNotEmpty(list)){
            deviceId.addAll(list);
        }
        if (CollectionUtil.isNotEmpty(deviceId)){
            JSONObject paramData = new JSONObject();
            paramData.put("channelIds",deviceId);
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
            sendOkHttpClient(endpoint +"v1/ai/apps/"+human_app_id+"/channels/unbind", "POST", body);
            sendOkHttpClient(endpoint +"v1/ai/apps/"+door_app_id+"/channels/unbind", "POST", body);
        }
    }

    @Override
    public JSONObject evsBeforeHandle() {
        JSONObject resultData = new JSONObject();
        return resultData;
    }

//    public static void main(String[] args) throws IOException {

//        Instant instant1 = LocalDateTime.now().plusHours(2).atZone(ZoneOffset.UTC).toInstant();
//        Instant instant2 = LocalDateTime.now().minusHours(2).atZone(ZoneOffset.UTC).toInstant();
//        Long start = instant2.toEpochMilli();
//        Long end = instant1.toEpochMilli();
//        System.out.println(LocalDateTime.now().plusHours(2).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
//        System.out.println(LocalDateTime.now().minusHours(2).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());


        //获取设备列表 OK
//        Object resultData = sendOkHttpClient(endpoint_cloud+"v1/device?pageNo=1&pageSize=10&spaceId=1006345&status=DEAD", "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));
////设备异常重试
//        JSONObject openParamData1 = new JSONObject();
//        RequestBody body1 = RequestBody.create(MediaType.parse("application/json"), "{}");
//        sendOkHttpClient(endpoint_cloud+"v1/device/onvif/1061543?retry", "PUT", body1);


//        String earliestEnterTime = "2023-10-20T16:56:10";
//        String latestEnterTime = "2023-10-20T17:02:10";
//        LocalDateTime localDateTime = LocalDateTime.parse(earliestEnterTime, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
//        LocalDateTime localDateTime1 = LocalDateTime.parse(latestEnterTime, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
//        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
//        ZonedDateTime zonedDateTime1 = localDateTime1.atZone(ZoneId.systemDefault());
//        Instant instant = zonedDateTime.toInstant();
//        Instant instant1 = zonedDateTime1.toInstant();
//        long timestamp = instant.toEpochMilli();
//        long timestamp1 = instant1.toEpochMilli();
//        System.out.println("时间戳： " + timestamp);
//        System.out.println("时间戳： " + timestamp1);

//        URL urlImage = new URL("D:\\a1a02d5ddb6db799a275ce3cf1c4beb.jpg");
//        HttpURLConnection connectionImage = (HttpURLConnection) urlImage.openConnection();
//        connection.setRequestProperty("Content-Length", String.valueOf(connectionImage.getContentLength()));
//        InputStream inputStream = urlImage.openStream();


//        String spaceId = "1006286";
//        String deviceId = "1061357";
//        String databaseId = "dbf-di2mesq4z6i9kffs";
//        String projectId = "327";
//        String appIdHu = "app-di2mcmmyr5n1sfjz";
//        String appIdHu1 = "app-di2mm8p0646jiuee";
//        String appIdMe = "app-di2mwqjye1gajt6q";
//        String memId = "fui-di2m2z729s4p3d7q,fui-di2m1jr21da4ptp5";
//        String picKey = "tmp/upload/fui-di2mpdr82uz5cfz8/di2mr0khk1rkxvyemci.jpg";

        //开启应用
//        JSONObject openParamData1 = new JSONObject();
//        openParamData1.put("status","enabled");
//        RequestBody body1 = RequestBody.create(MediaType.parse("application/json"), openParamData1.toString());
//        sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+human_app_id+"/status", "PUT", body1);

        //创建项目 OK
//        List<String> l = new LinkedList<>();
//        l.add("1006335");
//        JSONObject paramData = new JSONObject();
//        paramData.put("edgeId","1");
//        paramData.put("projectName","测试项目");
//        paramData.put("description","测试项目123456");
//        paramData.put("spaceIds",l.toArray());
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient("https://evs.bj.baidubce.com/v1/project", "POST", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));
//        {"projectId":333}

        //创建空间 OK
//        JSONObject paramData = new JSONObject();
//        paramData.put("spaceName","贵安数字孪生空间");
//        paramData.put("type","RTSP");
//        paramData.put("edgeId",1);
//        JSONObject paramData1 = new JSONObject();
//        paramData1.put("inviteImmediate",false);
//        paramData1.put("streamType","TCP");
//        paramData.put("gbProperties",paramData1);
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient("https://evs.bj.baidubce.com/v1/space", "POST", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));
//        {"spaceId":1006293,"domains":[{"domain":"di2rpmr7g0umcafucmr.down.evs.bcelive.com",
//            "cname":"di2rpmr7g0umcafucmr.down.evs.bcelive.com","type":"DOWNSTREAM"},
//            {"domain":"di2rxrsvyctcej2ii5c.down.evs.bcelive.com","cname":
//                "di2rxrsvyctcej2ii5c.down.evs.bcelive.com","type":"DOWNSTREAM"}]}

        //获取空间列表 OK
//        Object resultData = sendOkHttpClient(endpoint+"v1/space?pageNo=1&pageSize=10", "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //获取设备列表 OK
//        Object resultData = sendOkHttpClient("https://evs.bj.baidubce.com/v1/device?pageNo=1&pageSize=10&spaceId=1006345", "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //创建设备 OK
//        JSONObject paramData = new JSONObject();
//        paramData.put("spaceId",space_id);
//        paramData.put("deviceName","MDC01后摄像头3左冷通道1233-123456");
//        paramData.put("type","RTSP");
//        paramData.put("description","MDC01后摄像头3左冷通道1233-123456");
//        JSONObject paramData1 = new JSONObject();
//        paramData1.put("username","admin");
//        paramData1.put("password", "Hik12345+");
//        paramData1.put("rtspUri", "rtsp://admin:Hik12345+@10.194.221.4:554/Streaming/Channels/401");
//        paramData.put("rtspConfig",paramData1);
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient(endpoint+"v1/device", "POST", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));
//        {"deviceId":1061397}

        //获取设备 ok
//        Object resultData = sendOkHttpClient(endpoint+"v1/device/1000008", "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //获取通道列表
//        Object resultData = sendOkHttpClient("https://evs.bj.baidubce.com/v1/device/channel?deviceId="+deviceId
//            , "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //新增名单库 OK
//        JSONObject paramData = new JSONObject();
//        paramData.put("projectId",projectId);
//        paramData.put("type","human");
//        paramData.put("name","api创建名单库1");
//        paramData.put("description","api创建名单库测试");
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient("https://evs.bj.baidubce.com/v1/ai/databases", "POST", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //查询名单库 OK
//        Object resultData = sendOkHttpClient("https://evs.bj.baidubce.com/v1/ai/databases?type=human&projectId="+projectId+"&"+"pageNo=1&pageSize=50"
//            , "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //删除名单库 OK
//        Object resultData = sendOkHttpClient("https://evs.bj.baidubce.com/v1/ai/databases" +
//                "?ids=dbf-di2jrdpcykzkaxr2"
//            , "DELETE", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //新增名单库成员 OK
//        JSONObject paramData = new JSONObject();
//        paramData.put("picKey","");
//        JSONObject userData = new JSONObject();
//        userData.put("idCard","123456789876543214");
//        userData.put("name","superMan");
//        userData.put("gender","male");
//        userData.put("tel","18888888888");
//        userData.put("address","贵州省贵阳市");
//        paramData.put("property",userData);
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient(endpoint_cloud+"v1/ai/databases/dbf-di0mi8x9zqt6jb3b/members", "POST", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //查询名单库成员 OK
//        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/databases/"+database_id+"/members/search?pageNo=1&pageSize=50"
//            , "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //删除名单库成员 OK return null 单个删除
//        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/databases/"+database_id+"/members?ids=fui-djsuzjg1g6z44n8r", "DELETE", null);
//        System.out.println(resultData);

        //上传图片 OK
//        Object resultData = sendOkHttpClientFile(endpoint_ai+"v1/ai/databases/"+database_id+"/pic?uploadAuth"
//            , "GET", "/home/guian_storage/testai.png");
//        System.out.println(resultData.toString());

        //创建人员布控应用
//        JSONObject humAppParamData = new JSONObject();
//        humAppParamData.put("name","贵安数字孪生人员布控应用");
//        humAppParamData.put("type","human_surveillance");
//        humAppParamData.put("projectId",project_id);
//        humAppParamData.put("aiMode","view_computation");
//        humAppParamData.put("duration",1800000);
//        humAppParamData.put("databaseIds", new String[]{database_id});
//        RequestBody humBody = RequestBody.create(MediaType.parse("application/json"), humAppParamData.toString());
//        Object humResultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps", "POST", humBody);
//        System.out.println(humResultData);

        //创建开关门检测应用
//        JSONObject doorAppParamData = new JSONObject();
//        doorAppParamData.put("name","贵安数字孪生机柜开关门检测应用-prod");
//        doorAppParamData.put("type","open_door_abnormal_detection");
//        doorAppParamData.put("projectId",project_id);
//        doorAppParamData.put("aiMode","view_computation");
//        doorAppParamData.put("databaseIds", new String[]{database_id});
//        RequestBody doorBody = RequestBody.create(MediaType.parse("application/json"), doorAppParamData.toString());
//        Object doorResultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps", "POST", doorBody);
//        System.out.println(doorResultData);

        //开启应用
//        JSONObject openParamData1 = new JSONObject();
//        openParamData1.put("status","enabled");
//        RequestBody body1 = RequestBody.create(MediaType.parse("application/json"), openParamData1.toString());
//        sendOkHttpClient(endpoint+"v1/ai/apps/"+resultData.getString("humAppId")+"/status", "PUT", body1);

//        JSONObject openParamData2 = new JSONObject();
//        openParamData2.put("status","enabled");
//        RequestBody body2 = RequestBody.create(MediaType.parse("application/json"), openParamData2.toString());
//        sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+door_app_id+"/status", "PUT", body2);

        //查询应用列表 OK
//        Object resultData = sendOkHttpClient(endpoint_cloud+"v1/ai/apps/search?pageNo=1&pageSize=15", "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));
//
//        /**
//         * app-djhts5uvj81gjhw7
//         * app-djhtg7r62t6bw78m
//         * app-djht36payd3jmrk8
//         * app-djhtv13mk1t1qwnk
//         */
//       // app-djrtiif4rkbeq87k  app-djrst5cnssbzgyhw
//        //删除应用 OK return null 单个删除
////        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/app-djrtiif4rkbeq87k", "DELETE", null);
////        System.out.println(resultData);
//
//        //查询应用通道列表 OK
//        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+door_app_id+"/channels?pageNo=1&pageSize=10", "GET", null);
//        System.out.println(resultData);
//
//        //设备绑定AI应用 OK
//        JSONObject paramData = new JSONObject();
//        List<String> l = new LinkedList<>();
//        l.add("1000017");
//        l.add("1000018");
//        l.add("1000019");
//        l.add("1000020");
//        l.add("1000021");
//        l.add("1000022");
//        l.add("1000023");
//        l.add("1000024");
//        paramData.put("channelIds",l.toArray());
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+door_app_id+"/channels/bind", "POST", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //设备解绑AI应用 OK
//        JSONObject paramData = new JSONObject();
//        List<String> l = new LinkedList<>();
//        l.add("1000009");
//        l.add("1000010");
//        l.add("1000011");
//        l.add("1000012");
//        l.add("1000013");
//        l.add("1000014");
//        l.add("1000015");
//        l.add("1000016");
//        paramData.put("channelIds",l.toArray());
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+human_app_id+"/channels/unbind", "POST", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //更改应用状态 OK return null
//        JSONObject paramData = new JSONObject();
//        paramData.put("status","enabled");
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient("https://evs.bj.baidubce.com/v1/ai/apps/app-djim8ajpxe4kegp5/status", "PUT", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //更改应用 OK return null

//        String s = "{\n" +
//            "  \"type\": \"open_door_abnormal_detection\", \n" +
//            "  \"extractFrameInterval\": 1000, " +
//            "  \"humanConfidence\": 0.6, " +
//            "  \"openDoorConfidence\": 0.6, " +
//            "  \"callbackInterval\": 10000," +
//            "  \"triggerTime\": 20000, " +
//            "  \"endDelayTime\": 20000," +
//            "  \"effectiveTime\": {  " +
//            "        \"type\": \"WEEK\",\n" +
//            "        \"timePeriods\": [\n" +
//            "            {\n" +
//            "                \"startTime\": \"00:00:00\",\n" +
//            "                \"endTime\": \"23:59:59\",\n" +
//            "                \"dayInWeek\": 1 " +
//            "            },\n" +
//            "            {\n" +
//            "                \"startTime\": \"00:00:00\",\n" +
//            "                \"endTime\": \"23:59:59\",\n" +
//            "                \"dayInWeek\": 2" +
//            "            },\n" +
//            "            {\n" +
//            "                \"startTime\": \"00:00:00\",\n" +
//            "                \"endTime\": \"23:59:59\",\n" +
//            "                \"dayInWeek\": 3 " +
//            "            },\n" +
//            "            {\n" +
//            "                \"startTime\": \"00:00:00\",\n" +
//            "                \"endTime\": \"23:59:59\",\n" +
//            "                \"dayInWeek\": 4 " +
//            "            },\n" +
//            "            {\n" +
//            "                \"startTime\": \"00:00:00\",\n" +
//            "                \"endTime\": \"23:59:59\",\n" +
//            "                \"dayInWeek\": 5 " +
//            "            },\n" +
//            "            {\n" +
//            "                \"startTime\": \"00:00:00\",\n" +
//            "                \"endTime\": \"23:59:59\",\n" +
//            "                \"dayInWeek\": 6 " +
//            "            },\n" +
//            "            {\n" +
//            "                \"startTime\": \"00:00:00\",\n" +
//            "                \"endTime\": \"23:59:59\",\n" +
//            "                \"dayInWeek\": 7 " +
//            "            }\n" +
//            "        ]\n" +
//            "    }\n" +
//            "}\n";
//        JSONObject paramData = JSONObject.parseObject(s);
////        paramData.put("duration",1800000);
////        paramData.put("description","贵安数字孪生人员布控应用-prod");
//        RequestBody body = RequestBody.create(MediaType.parse("application/json"), paramData.toString());
//        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+door_app_id+"/config/open_door_abnormal_detection", "PUT", body);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //查询应用详情 OK
//        Object resultData = sendOkHttpClient(endpoint_ai+"v1/ai/apps/"+human_app_id, "GET", null);
//        System.out.println(resultData);

        //拉取AI事件 OK
//        Instant instant1 = LocalDateTime.now().plusMinutes(30).atZone(ZoneOffset.UTC).toInstant();
//        Instant instant2 = LocalDateTime.now().minusMinutes(10).atZone(ZoneOffset.UTC).toInstant();
//        Long start = instant2.toEpochMilli();
//        Long end = instant1.toEpochMilli();
//        System.out.println(start+"==="+end);
//        Object resultData = sendOkHttpClient(endpoint_cloud+"api/v2/ai/event/list?begin="+start+"&end="+end+"&maxSize=50&eventType=human_surveillance&appId=app-dkaj9avsvc1g4irt"
//            , "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));

        //拉取AI事件详情
//        Object resultData = sendOkHttpClient(endpoint_ai+"api/v2/ai/event/result/list?eventId=odr-djtsm6qc4ftwjifg&maxSize=50&eventType=open_door_abnormal_detection"
//            , "GET", null);
//        System.out.println(JSONObject.parseObject(resultData.toString()));
//    }


    /**
     * 文件上传
     * @param requestUrl
     * @return
     */
    public static Object sendOkHttpClientFile(String requestUrl, String requestMethod, String fileUrl){
        OkHttpClient client = new OkHttpClient();
        client.setConnectTimeout(10, TimeUnit.SECONDS);
        client.setReadTimeout(10, TimeUnit.SECONDS);
        client.setWriteTimeout(10, TimeUnit.SECONDS);
        Request request = generateAuthorizedRequest(requestMethod, requestUrl, AK, SK, null);

        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                JSONObject fileJson = JSONObject.parseObject(response.body().string());
                String pic_key = fileJson.getString("key");
                String pre_sign_url = fileJson.getString("preSignUrl");

                uploadFile(pre_sign_url,fileUrl);
                System.out.println(pre_sign_url);
                return pic_key;
            } else {
                System.out.println("Request failed: " + response.code() + " - " + response.message());
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void uploadFile(String preSignUrl, String filePath) throws IOException {
        // 创建URL对象
        URL url = new URL(preSignUrl);

        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // 设置请求方法为POST
        connection.setRequestMethod("PUT");

        // 允许输入输出
        connection.setDoOutput(true);
        connection.setDoInput(true);

        // 设置请求头
        connection.setRequestProperty("Content-Type", "application/octet-stream");

        // 读取文件内容并写入输出流
        try {
            filePath = StringUtils.encodeChineseInUrl(filePath);
            URL urlImage = new URL(filePath);
            HttpURLConnection connectionImage = (HttpURLConnection) urlImage.openConnection();
            connection.setRequestProperty("Content-Length", String.valueOf(connectionImage.getContentLength()));
            InputStream inputStream = urlImage.openStream();
//            InputStream inputStream = new FileInputStream(filePath);
            OutputStream outputStream = connection.getOutputStream();

            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        // 获取响应码
        int responseCode = connection.getResponseCode();
        System.out.println("Response Code: " + responseCode);

        // 关闭连接
        connection.disconnect();
    }

    /**
     * 发送GET请求
     * @param requestUrl
     * @return
     */
    public static Object sendOkHttpClient(String requestUrl, String requestMethod, RequestBody body){
        OkHttpClient client = new OkHttpClient();
        client.setConnectTimeout(10, TimeUnit.SECONDS);
        client.setReadTimeout(10, TimeUnit.SECONDS);
        client.setWriteTimeout(10, TimeUnit.SECONDS);
        Request request = generateAuthorizedRequest(requestMethod, requestUrl, AK, SK, body);

        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                System.out.println(response.header("X-Bce-Request-Id"));
                return response.body().string();
            } else {
                String errorMessage = response.header("X-Bce-Error-Message");
                String requestId = response.header("X-Bce-Request-Id");
                System.out.println("Request failed: " + response.code() + " - "
                    + response.message() + " - " + errorMessage + " - " + requestId);
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Request generateAuthorizedRequest(String method, String url, String ak, String sk, RequestBody body) {
        String xBceDate = convertTimestampToUTCString(System.currentTimeMillis());

        HttpUrl httpUrl = HttpUrl.parse(url);
        String query = httpUrl.query();
        String uri = httpUrl.encodedPath();
        String host = httpUrl.host();

        Map<String, String> headers = new HashMap<>();
        headers.put("Host", host);
        headers.put("x-bce-date", xBceDate);

        String authStringPrefix = String.format("bce-auth-v1/%s/%s/1800", ak, xBceDate);
        // Canonical Query String
        String canonicalQuery = genCanonicalQueryString(query);
        // Canonical Headers
        Map<String, String> canonicalHeaders = canonicalHeadersFilter(headers);
        String signedHeaders = canonicalHeaders.keySet().stream().sorted().collect(Collectors.joining(";"));
        String canonicalHeadersStr = canonicalHeaders.entrySet().stream()
            .sorted(Comparator.comparing(Map.Entry::getKey))
            .map(entry -> entry.getKey() + ":" + URLEncoder.encode(entry.getValue())).
                collect(Collectors.joining("\n"));
//        String canonicalHeadersStr = "host:127.0.0.1;x-bce-date:" + xBceDate;
        // Canonical Request
        String canonicalRequest = method + "\n" + uri + "\n" + canonicalQuery + "\n" + canonicalHeadersStr;
        // Signing Key
        String signingKey = byteToHex(hmacSHA256(sk, authStringPrefix));
        // Signature
        byte[] signature = hmacSHA256(signingKey, canonicalRequest);
        String authorization = authStringPrefix + "/" + signedHeaders + "/" + byteToHex(signature);
        headers.put("Authorization", authorization);

        return new Request.Builder()
            .url(url)
            .method(method, body != null ? body : null)
            .headers(Headers.of(headers))
            .build();
    }

    public static String genCanonicalQueryString(String query) {
        if (query == null) {
            return "";
        }

        List<String> params = new ArrayList<>();
        for (String param : query.split("&")) {
            String[] keyValue = param.split("=");
            if (keyValue.length == 2) {
                params.add(keyValue[0] + "=" + keyValue[1]);
            } else {
                params.add(keyValue[0] + "=");
            }
        }

        params.sort(String::compareTo);
        return String.join("&", params);
    }

    public static Map<String, String> canonicalHeadersFilter(Map<String, String> headers) {
        Map<String, String> filteredHeaders = new HashMap<>();
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            String key = entry.getKey().toLowerCase();
            String value = entry.getValue();
            if ("host".equals(key) || key.startsWith("x-bce-")) {
                filteredHeaders.put(key, value);
            }
        }
        return filteredHeaders;
    }

    public static byte[] hmacSHA256(String key, String data) {
        try {
            Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            hmacSHA256.init(secretKey);
            return hmacSHA256.doFinal(data.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
            return new byte[0];
        }
    }

    public static byte[] hmacSHA256(byte[] key, String data) {
        try {
            Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(key, "HmacSHA256");
            hmacSHA256.init(secretKey);
            return hmacSHA256.doFinal(data.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
            return new byte[0];
        }
    }

    public static String byteToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    public static String convertTimestampToUTCString(long timestampMillis) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        format.setTimeZone(TimeZone.getTimeZone("GMT+0"));
        return format.format(new Date(timestampMillis));
    }

}
